package com.map.controller;

import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;
import org.springframework.web.servlet.view.RedirectView;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;

import com.map.domain.ContentWriter;
import com.map.domain.Website;
import com.map.domain.BaseUrl;
import com.map.service.socketCommunication;

import java.io.*;
import java.net.Socket;
import java.net.URLEncoder;
import java.net.UnknownHostException;
import java.util.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@Controller
public class MainController{
	private socketCommunication sendMessage = new socketCommunication();

	@RequestMapping(value = "/Geomap", method = RequestMethod.GET)
	public ModelAndView Geomap() throws IOException { 
		BaseUrl weblist = new BaseUrl("baseurl.txt");
		System.out.println("Baseurl object: weblist is created here");
		return new ModelAndView("Geomap", "command", weblist);
	}
	
	
	@RequestMapping(value = "/getUrl", method = { RequestMethod.GET,
			RequestMethod.POST })
	public @ResponseBody
	List<String> findUrl(Model model) {
		List<String> webList = new LinkedList<String>();
		String hostName = "localhost";
		int portNumber = 31039;// port is defined to be 31039
		try (Socket echoSocket = new Socket(hostName, portNumber);
				DataOutputStream out = new DataOutputStream(echoSocket.getOutputStream());
				BufferedReader in = new BufferedReader(new InputStreamReader(
						echoSocket.getInputStream()));) {
			String newUrl=null,time=null;
			//System.out.println("before read");
			out.write(10);//instruction written
			//out.write(5);// 5 to indicate that I want some address
			//out.write(2);//2 to indicate that I want 2 more addresses
			while ((newUrl = in.readLine()) != null) {
				//System.out.println("After read");
				if (newUrl.equals("")) {
					break;
				}
				
				time=in.readLine();
				if(!newUrl.equals(""))webList.add(newUrl+" "+time);
				System.out.println("echo:" + newUrl+ " "+time+"ms");
			}
		//for(int i=0;i<3;i++)
			//{
			//newUrl = in.readLine();// here each time I only get one from the crawler
			//time=in.readLine();
			//if(newUrl!=null&&!newUrl.equals(""))
				//{
				//webList.add(newUrl+" "+time);
				//System.out.println("echo:" + newUrl+ " "+time+"ms");
			//	}
			//}
			
			System.out.println("Number of URLs read this time"+webList.size());

			in.close();
			echoSocket.close();
		} catch (UnknownHostException e) {
			System.out.println("Don't know about host " + hostName);
			System.exit(1);
		} catch (IOException e) {
			System.out.println("Sorry Jim, Couldn't get I/O for the connection to "
					+ hostName);
			System.exit(1);
		}
		return webList;
	}
	
/*@RequestMapping(value = "/getUrl", method = { RequestMethod.GET,
			RequestMethod.POST })
	public @ResponseBody
	List<String> findUrl(Model model) {
		List<String> webList = new LinkedList<String>();
		webList.add("www.google.com 4000");
		webList.add("www.google.com.sg 2000");
		webList.add("www.sina.com 5000");
		webList.add("www.baidu.com 3000");
		webList.add("www.nus.edu.sg 3000");
		webList.add("www.ntu.edu.sg 3000");
		webList.add("www.sina.com.cn 3000");
		webList.add("www.baidu.com 2000");
		webList.add("www.google.com 2000");
		webList.add("www.nus.edu.sg 2000");
		webList.add("www.bbc.com 2000");
		webList.add("www.w3schools.com 2000");
		webList.add("www.lib.nus.edu.sg 2000");
		webList.add("meta.stackoverflow.com 2000");
		webList.add("careers.stackoverflow.com 3000");
		webList.add("stackexchange.com 3000");
		webList.add("www.heartinternet.co.uk 3000");
		webList.add("www.eukhost.com 3000");
		webList.add("bbs.english.sina.com 3000");
		webList.add("sina.echineselearning.com 3000");
		webList.add("roll.news.sina.com.cn 4000");
		webList.add("www.wix.com 4000");
		webList.add("www.weibo.com 4000");
		webList.add("cn.nus.edu.sg 4000");
		webList.add("president.nus.edu.sg 3000");
		webList.add("www.overseas.nus.edu.sg 3000");
		webList.add("www.fas.nus.edu.sg 2000");
		webList.add("www.nusentrepreneurshipcentre.sg 2000");
		webList.add("www.echineselearning.com 2000");
		webList.add("www.nusri.cn 2000");
		webList.add("security.stackexchange.com 2000");
		webList.add("chi.nus.edu.sg 2000");
		webList.add("resources.echinesellcademia.stackexchange.com 2000");
		webList.add("earning.com 2000");
		webList.add("www.iss.nus.edu.sg 2000");
		webList.add("matheducators.stackexchange.com 2000");
		webList.add("codereview.stackexchange.com 3000");
	return webList;
	}*/

	@RequestMapping(value = "/Geomap", method = RequestMethod.POST,params="start")
	public ModelAndView addUrl(HttpServletRequest request, BaseUrl weblist) throws FileNotFoundException {
		//model.addAttribute("baseurl", weblist.getBaseurl());
		System.out.println("Base URL wish to send before check: "+weblist.getBaseurl());
		if(!weblist.getBaseurl().endsWith("\n"))weblist.setBaseurl(weblist.getBaseurl()+"\n");// to make sure the outgoing format is correct, end with \n
		weblist.setListfromBaseUrl(weblist.getBaseurl());
		weblist.setNumUrl(weblist.getNumfromList());
		
		if (request.getParameter("sn") != null
				&& !request.getParameter("sn").equals("")) {
			
			if (request.getParameter("sn").equals("true")) {
				System.out.println("Base URL sent this time: "+weblist.getBaseurl());
				     sendMessage.sendUrl(weblist);
					}
			
			else 
				{
				System.out.println("Send a resume");
				sendMessage.resume();
				
				}
				}
		
		
		PrintWriter writer = new PrintWriter("baseurl.txt");
		writer.println(weblist.getBaseurl());
		writer.close();
		return new ModelAndView(new RedirectView("Geomap"));
	}

	/*@RequestMapping(value = "/Geomap", method = RequestMethod.POST, params="stop")
	public  ModelAndView stopCrawling(HttpServletRequest request, BaseUrl weblist) throws IOException
	{
		//String filename;
		
		sendMessage.stop();
	
		return this.Geomap();
	}*/
	
	@RequestMapping(value = "/sendStop", method = { RequestMethod.GET,
			RequestMethod.POST })
	public @ResponseBody
    void  sendStop() {
		sendMessage.stop();
		String tmp="stop done";
		System.out.println(tmp);
	}
	
	@RequestMapping(value = "/sendResume", method = { RequestMethod.GET,
			RequestMethod.POST })
	public @ResponseBody
	List<String> sendResume(Model model) {
		List<String> tmp= new LinkedList<String>();
		System.out.println("Inside /sendResume");
		sendMessage.resume();
		return tmp;//to fire the call back function
	}
	
	
	@RequestMapping(value = "/sendRestart", method = { RequestMethod.GET,
			RequestMethod.POST })
	public @ResponseBody
	List<String>  sendRestart(@RequestBody BaseUrl weblist) throws FileNotFoundException {
		
		System.out.println("Inside sendRestart!!!!!!!!!!");
		List<String> tmp= new LinkedList<String>();
		if(!weblist.getBaseurl().endsWith("\n"))weblist.setBaseurl(weblist.getBaseurl()+"\n");// to make sure the outgoing format is correct, end with \n
		weblist.setListfromBaseUrl(weblist.getBaseurl());
		weblist.setNumUrl(weblist.getNumfromList());
		
		/*if(!baseurl.endsWith("\n"))
			{
			System.out.println("Not end with \\n");
			  baseurl=baseurl+"\n";// to make sure the outgoing format is correct, end with \n
			}
		BaseUrl weblist = new BaseUrl();
		weblist.setBaseurl(baseurl);
		weblist.setListfromBaseUrl(weblist.getBaseurl());
		weblist.setNumUrl(weblist.getNumfromBaseUrl(weblist.getBaseurl()));*/
		//System.out.println("data passed is: "+baseurl);
		sendMessage.sendUrl(weblist);
		System.out.println("Base URL Read this time: "+weblist.getBaseurl()+" before writing to the baseurl.txt");
		System.out.println("number of urls sent this time: "+ weblist.getNumUrl());
		
		PrintWriter writer = new PrintWriter("baseurl.txt");
		writer.println(weblist.getBaseurl());
		writer.close();
		System.out.println("File write to baseurl.txt done");
		return tmp;// to fire the call back function
	}
	
	
	@RequestMapping(value = "/getTree", method = { RequestMethod.GET,
			RequestMethod.POST })
	public @ResponseBody
	List <String> getTree( @RequestBody BaseUrl weblist) throws FileNotFoundException
	{
		System.out.println("haha, inside getTree!");
		System.out.println("number of urls received: "+ weblist.getUrlList().size());
		List<String> dummy= new ArrayList<String>();
		PrintWriter writer = new PrintWriter("treeURL.txt");
		writer.flush();
		for(int i=0;i<weblist.getUrlList().size();i++)
		writer.println(weblist.getUrlList().get(i));
		writer.close();
		//return new ModelAndView(new RedirectView("Tree"));
		return dummy;

	}
	
	
	/*@RequestMapping(value = "/Tree", method = RequestMethod.GET)
	public ModelAndView Tree() throws IOException { 
	
		return new ModelAndView("Tree");
	}
	
	@RequestMapping(value = "/getData", method = RequestMethod.GET)
	public @ResponseBody
	List<String> getTreedata() throws IOException { 
	System.out.println("Inside get Tree Data!!! can pass back the json file");
	List<String> dummy= new ArrayList<String>();
		return dummy;
	}*/
	
	@RequestMapping(value = "/load", method = { RequestMethod.GET,
			RequestMethod.POST })
	public @ResponseBody
	List<String> load(@RequestBody ContentWriter cw) {
	return ContentWriter.readHistory(cw.getFilepath(), cw.getFilename());
	}
	
	
	@RequestMapping(value = "/writeList", method = { RequestMethod.GET,
			RequestMethod.POST })
	public @ResponseBody
	List <String> writeList( @RequestBody ContentWriter cw) 
	{
		System.out.println("haha, inside ContentWriter");
		List<String> dummy= new ArrayList<String>();
	
		cw.writeListtoFile();
		return dummy;

	}
}



